﻿package Base.Net 
{
	import Base.Log.LogManager;
	
	import flash.errors.*;
	import flash.events.*;
	import flash.net.Socket;
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	import flash.utils.Timer;
	
	
	/**
	 * ...
	 * @author fox
	 */
	public class NetSocket extends Socket 
	{
		private var host:String = "";
		private var port:int = 0;
		private var valid:Boolean = false;
		private var timer:Timer = null;
		
		public function NetSocket() 
		{
			data = new ByteArray();
			data.endian = Endian.LITTLE_ENDIAN;
			
			timer = new Timer( 200 );
			timer.addEventListener( TimerEvent.TIMER , onTimer );
			
			// endian ,
			endian = Endian.LITTLE_ENDIAN;
			
			addEventListener( Event.CLOSE , onClose );
			addEventListener( Event.CONNECT , onConnect );
			addEventListener( IOErrorEvent.IO_ERROR , onError );
			addEventListener( SecurityErrorEvent.SECURITY_ERROR , onSecurityError );
			addEventListener( ProgressEvent.SOCKET_DATA , OnReceive );
		}
		
		// connect is valid	
		public function isValid():Boolean
		{
			return valid;
		}
		
		
		// connect host 
		public function Connect( host:String , port:int ):void
		{
			this.host = host;
			this.port = port;
			
			connect( host , port );
		}
		
		
		// send msg
		public function Send():void
		{
			if ( !connected )
			{
				connect( host , port );
				return;
			}
			
			flush();
		}
		
		//////////////////////////////////////////////////////////////
		
		// on Security Error
		private function onSecurityError( event:SecurityErrorEvent ):void
		{
			valid = false;
			
			LogManager.logOut(event.toString());
			
			var netEvnet:NetEvent = new NetEvent( NetEvent.ERROR );
			dispatchEvent(netEvnet);
		}
		
		// on error
		private function onError( event:IOErrorEvent ):void
		{
			valid = false;
			
			LogManager.logOut(event.toString());
			
			var netEvnet:NetEvent = new NetEvent( NetEvent.ERROR );
			dispatchEvent(netEvnet);
		}
		
		
		// on connect
		private function onConnect( event:Event ):void
		{
			valid = true;
			
			LogManager.logOut(event.toString());
			
			var netEvnet:NetEvent = new NetEvent( NetEvent.CONNECT );
			dispatchEvent(netEvnet);
			
			timer.start();
		}
		
		// on close
		private function onClose( event:Event ):void
		{
			valid = false;
			
			LogManager.logOut(event.toString());
			
			var netEvnet:NetEvent = new NetEvent( NetEvent.CLOSE );
			dispatchEvent(netEvnet);
			
			timer.stop();
		}
		
		
		private var netWait:Boolean = false;
		private var wait:Boolean = false;
		private var netWaitSize:int = 0;
		private var netWaitType:int = 0;
		private var data:ByteArray = null;
		
		private function onTimer( e:TimerEvent ):void
		{
			if ( bytesAvailable != 0 )
			{
				if ( netWait || wait )
				{
				}
				else
				{
					var size:int = readShort();
					var type:int = readShort();
					
					netWaitSize = size;
					netWaitType = type;
					
					LogManager.logOut( "net type = " + netWaitType + "  net size = " + netWaitSize );
				}
				
				if ( netWaitSize > bytesAvailable + 4 )
				{
					netWait = true;
					return;
				}
				
				if ( NetEvent.members[ netWaitType ] )
				{
					data.clear();
					readBytes( data , 0 , netWaitSize - 4 );
					
					NetEvent.members[ netWaitType ]( data );
					
					wait = false;
				}
				else
				{
					wait = true;
				}
				
				netWait = false;
				
			}
		}
		
		// on recv
		private function OnReceive( event:ProgressEvent ):void
		{
			//LogManager.logOut(event.toString());
			
		}
	}
	
}


